package containerlogistik.implementation;

import containerlogistik.interfaces.Angle;

public class AngleInRad extends AbstractValue<Angle> implements Angle {
    
    private static final int MAX_DEG = 360;
    
    private double rad;

    private AngleInRad(double rad) {
        this.rad = rad;
    }

    static AngleInRad valueOf(double rad) {
        return new AngleInRad(rad);
    }

    @Override
    public double rad() {
        return this.rad;
    }

    @Override
    public double deg() {
        return this.rad * Values.RAD_IN_DEG;
    }
    
    @Override
    public boolean isZero() {
        return (this.equals(Values.ZERO_ANGLE));
    }

    @Override
    public boolean isValid() {
        return true;
    }

    @Override
    public Angle add(Angle value) {
        return Values.angleInDeg((this.deg() + value.deg()) % MAX_DEG);
    }

    @Override
    public Angle sub(Angle value) {
        return Values.angleInDeg((this.deg() - value.deg()) % MAX_DEG);
    }

    @Override
    public Angle mul(double factor) {
        return Values.angleInDeg((this.deg() * factor) % MAX_DEG);
    }

    @Override
    public Angle div(double factor) {
        return Values.angleInDeg((this.deg() / factor) % MAX_DEG);
    }

    @Override
    public Angle inverse() {
        return Values.angleInRad(-this.rad());
    }

    @Override
    public double div(Angle value) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public String toString() {
        return String.format("AngleInRad{rad=%.2f, deg=%.2f}",
                this.rad(), this.deg());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof Angle)) return false;
        return this.compareTo((Angle)obj) == 0;
    }

    @Override
    public int hashCode() {
        return hashDouble(this.rad());
    }
    
    public int compareTo(Angle o) {
        return Double.compare(this.rad(), o.rad());
    }
    
}
